﻿using System.Text;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

namespace FlyingHat.Common.Helper.Image
{
    /// <summary>
    /// 图片帮助类
    /// </summary>
    public class CaptchaHelper
    {

        #region GIF验证码
        // 验证码伪随机即可，因此使用Random
        private readonly Random imageRandom = new();
        /// <summary>
        /// 去除了容易混淆的0,1,i,j
        /// </summary>
        private readonly string[] texts = new string[] { "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "k", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
        /// <summary>
        /// 较深的颜色--用于文字
        /// </summary>
        private readonly string[] colorHex = new string[] { "#ff461f", "#ff2d51", "#000000", "#00e500", "#44cef6", "#622a1d", "#065279", "#4b5cc4", "#191970", "#ff7500", "#0eb83a", "#801dae", "#ff0097", "#9d2933", "#56004f", "#c3272b" };
        /// <summary>
        /// 较浅的颜色--用于背景
        /// </summary>
        private readonly string[] lightColorHex = new string[] { "#e3f9fd", "#fcefe8", "#F0FFFF", "#e9e7ef", "#c0ebd7", "#FFE4E1", "#a4e2c6", "#eedeb0" };

        /// <summary>
        /// 字体池
        /// </summary>
        private static List<Font> Fonts = new();

        public CaptchaHelper()
        {
            Fonts = InitFonts();
        }

        /// <summary>
        /// 验证码图片宽高
        /// </summary>
        private readonly int imageWidth = 120;
        private readonly int imageHeight = 50;

        /// <summary>
        /// 初始化字体池
        /// </summary>
        /// <param name="fontSize">一个初始大小</param>
        private List<Font> InitFonts()
        {
            if (Fonts.Count == 0)
            {
                var fontDir = Path.Combine(AppContext.BaseDirectory, "Config", "fonts");
                if (Directory.Exists(fontDir))
                {
                    var fontFiles = Directory.GetFiles(fontDir, "*.ttf");
                    var fontCollection = new FontCollection();

                    if (fontFiles?.Length > 0)
                    {
                        foreach (var ff in fontFiles)
                        {
                            Fonts.Add(new Font(fontCollection.Install(ff), imageHeight));
                        }
                    }
                }
                else
                {
                    throw new Exception($"绘制验证码字体文件不存在，请将字体文件(.ttf)复制到目录：{fontDir}");
                }
            }
            return Fonts;
        }


        /// <summary>
        /// 生成随机英文字母/数字组合字符串
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public string GetRandomText(int length = 4)
        {
            StringBuilder sb = new();
            if (length > 0)
            {
                // 对texts数组做随机排序
                var textTemp = texts.OrderBy(i => imageRandom.Next()).ToArray();
                var textLength = texts.Length;
                for (int i = 0; i < length; i++)
                {
                    var index = imageRandom.Next(0, textLength);
                    sb.Append(textTemp[index]);
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 动态(gif)数字字母组合验证码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public byte[] GetGifCodeByte(string text)
        {
            // 绘制背景图
            using Image<Rgba32> img = GetCodeImage(text);
            var ran = imageRandom.Next(50, 100);
            for (int i = 0; i < 5; i++)
            {
                // 绘制图片层字符图片
                using Image<Rgba32> tempImg = GetCodeImage(text);
                // 设置GIF元数据属性--延迟展示时间
                tempImg.Frames[0].Metadata.GetGifMetadata().FrameDelay = ran;
                img.Frames.AddFrame(tempImg.Frames[0]);
                // 设置GIF元数据属性--延迟展示时间
                img.Frames[i].Metadata.GetGifMetadata().FrameDelay = ran;
            }
            // 重复无限次
            img.Metadata.GetGifMetadata().RepeatCount = 0;
            using var ms = new MemoryStream();
            img.Save(ms, new GifEncoder());
            return ms.ToArray();
        }

        private Image<Rgba32> GetCodeImage(string text)
        {
            Image<Rgba32> img = new(imageWidth, imageHeight);
            var fonts = InitFonts();
            img.Mutate(i => i
                // 填充背景图
                .Fill(Color.ParseHex(lightColorHex[imageRandom.Next(0, lightColorHex.Length)]))
                // 发光效果
                .Glow(Color.ParseHex(lightColorHex[imageRandom.Next(0, lightColorHex.Length)]))
                // 绘制干扰线
                .DrawGridLines(8, Color.ParseHex(lightColorHex[imageRandom.Next(0, lightColorHex.Length)]), imageWidth, imageHeight, imageRandom)
                // 绘制文字
                .DrawGridText(text, imageWidth, imageHeight, fonts, colorHex, imageRandom)
                // 高斯模糊
                .GaussianBlur(0.5f)
            );
            return img;
        }




        #endregion
    }



}
